-- SuitM
-- Create by zouyb
-- 套装

module("SuitM", package.seeall);

-- 所有的套装信息
local suits = {};
local suit_map = {};

-- 载入配置表
local _init = false;
local loadCsv = function()
    if _init then return end
    _init = true;

    -- 转换下equip信息表
    local suit_CSV = get_suit_CSV();
    for i = 1, #suit_CSV do
        suits[suit_CSV[i].id] = suit_CSV[i];
    end
    suit_CSV = {};

    for id, row in pairs(suits) do
        for _, class_id in pairs(row["active"]) do
            suit_map[class_id] = id;
        end
    end
end

-- 模块初始化
function init()
    loadCsv();
end

function get_suit_id(class_id)
    return suit_map[class_id] or 0;
end

-- 检索套装信息
function query(id, path)
    local m = suits[id];
    if (path == "" or path == nil) then
        return m;
    else
        return m[path];
    end
end

-- 获取套装的属性
function calcSuitBaseProp(suitId)
    local prop = query(suitId, "prop");
    if type(prop) == 'table' then
        return table.deepcopy(prop);
    end

    if type(prop) == "string" then
        return FormulaM.invoke(prop, ME.user, suitId);
    end

    return {};
end

-- 获取套装激活的属性
function getSuitProp(equipList)
    local props = {};

    local function isSubTable(t1, t2)
        for i = 1, #t1 do
            if table.indexOf(t2, t1[i]) == -1 then
                return false;
            end
        end

        return true;
    end

    for _, row in pairs(suits) do
        if isSubTable(row.active, equipList) then
            props = table.append(props, calcSuitBaseProp(row.id));
            
            -- 工程学手册对套装的加成属性
            local manualAddition = EngineeringManualM.getManualAddition(row.id, "equip");
            if manualAddition then
                props = table.append(props, manualAddition);
            end
        end
    end

    return props;
end

-- 判断是否有某个装备的套装
function isSuitByEquipId(equipList, equipId)
    local suitInfo = getSuitInfoByEquipId(equipId);

    if type(suitInfo) ~= 'table' or type(equipList) ~= 'table' and
       0 == #suitInfo or 0 == #equipList then
        -- 没有相关套装信息
        return false;
    end

    local function isSubTable(t1, t2)
        for i = 1, #t1 do
            if table.indexOf(t2, t1[i]) == -1 then
                return false;
            end
        end

        return true;
    end

    if type(suitInfo.active) ~= "table" then
        return false;
    end

    return isSubTable(suitInfo.active, equipList);
end

-- 获取某个装备的套装信息
function getSuitInfoByEquipId(equipId)
    local retInfo = {};
    for id, suitInfo in pairs(suits) do
        if table.indexOf(suitInfo.active, equipId) ~= -1 then
            retInfo = suitInfo;
            break;
        end
    end
    return retInfo;
end

-- 获取某个装备的套装的某加成信息
function getSuitPropByEquipId(equipId, propName)
    local retProp = {};
    -- 套装信息
    local suitInfo = getSuitInfoByEquipId(equipId);
    local props = calcSuitBaseProp(suitInfo.id);

    -- 工程学手册对套装的加成属性
    local manualAddition = EngineeringManualM.getManualAddition(suitInfo.id, "equip");
    if manualAddition then
        props = table.append(props, manualAddition);
    end

    for _, prop in pairs(props) do
        if prop[2] == propName then
            retProp = prop;
            break;
        end
    end
    return retProp;
end

-- 获取套装配置表
function getAllSuits()
    return table.deepcopy(suits);
end

-- 判断某件装备是否能合成
function canMergeEquip(class_id)
    local suit_id = get_suit_id(class_id);
    if not suit_id or suit_id <= 0 then
        return false;
    end

    return canMergeSuit(suit_id);
end

-- 判断某套装是否能合成
function canMergeSuit(suit_id)
    -- 1. 先判断是否能融合
    local prop = PropM.combine(ME.user, "merge_suit", suit_id);
    if prop[3] <= 0 then
        trace("SuitM", "没有融合套装%d的属性", suit_id);
        return false;
    end

    local suit_info = SuitM.query(suit_id);
    if not suit_info or type(suit_info["merge_bonus"]) ~= "number" then
        trace("SuitM", "套装%d不能融合", suit_id);
        return false;
    end

    local equipments = ME.user.equipments or {};

    -- 2. 必须全部穿戴整齐
    for _, class_id in pairs(suit_info["active"]) do
        local equip_pos = EquipM.query(class_id, "type");

        if sizeof(equipments[equip_pos]) <= 0 or class_id ~= equipments[equip_pos][1] then
            trace("SuitM", "没有穿戴装备%d", class_id);
            return false;
        end
    end

    return true;
end

-- 能否显示融合按钮
function canShowBtnMerge(suit_id)
    -- 1. 先判断是否能融合
    local prop = PropM.combine(ME.user, "merge_suit", suit_id);
    if prop[3] <= 0 then
        return false;
    end

    local suit_info = SuitM.query(suit_id);
    if not suit_info or type(suit_info["merge_bonus"]) ~= "number" then
        return false;
    end

    local equipments = ME.user.equipments or {};

    -- 2. 穿戴整齐，或者包裹里有
    for _, class_id in pairs(suit_info["active"]) do
        local equip_pos = EquipM.query(class_id, "type");

        if (sizeof(equipments[equip_pos]) <= 0 or 
            class_id ~= equipments[equip_pos][1])
            and ItemM.getAmount(ME.user, class_id) < 0 then
            return false;
        end
    end

    return true;
end

-- 融合套装
function mergeSuit(suit_id)
    if not canMergeSuit(suit_id) then
        return false;
    end

    -- 直接把装备扣除掉
    local suit_info = SuitM.query(suit_id);
    local equipments = ME.user.equipments or {};
    for _, class_id in pairs(suit_info["active"]) do
        local equip_pos = EquipM.query(class_id, "type");

        equipments[equip_pos] = nil;
    end

    -- 奖励目标
    BonusM.doBonus({ 1, suit_info["merge_bonus"], 1 }, "merge_suit");

    -- 最后需要处理下hp、mp，如果为0则强制设置为1
    PropM.refreshEffect(ME.user, "equip");

    local hp = ME.user:queryAttrib("hp");
    local mp = ME.user:queryAttrib("mp");
    if hp <= 0 then
        ME.user:addAttrib("hp", -hp + 1);
    end
    if mp <= 0 then
        ME.user:addAttrib("mp", -mp + 1);
    end

    return true;
end
